home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / cross / ava-0.2.5.lha / ava-0.2.5 / src / Preproc.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-23  |  4.2 KB  |  167 lines

  1. /*
  2.     Preproc.C
  3.     
  4.     Preprocessor
  5.     Uros Platise, July 1998
  6. */
  7.  
  8. #include <sys/stat.h>
  9. #include <unistd.h>
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include "Lexer.h"
  13. #include "Syntax.h"
  14. #include "Preproc.h"
  15. #include "Error.h"
  16.  
  17. TFile::TFile():temporary(false),fd(NULL),bufferCh(false),ch(0){}
  18.  
  19. TFile::TFile(const char* _fullName, const char* _mode="rt", 
  20.              bool _temporary=false):
  21.   temporary(false),fd(NULL),bufferCh(false),ch(0){
  22.   reopen(_fullName, _mode, _temporary);
  23. }
  24.  
  25. TFile::~TFile(){
  26.   if (fd!=NULL){fclose(fd);if (temporary==true){unlink(name);}}
  27. }
  28.  
  29. void TFile::reopen(const char* _fullName, const char* _mode="rt", 
  30.                    bool _temporary=false){
  31.   assert(fd==NULL);
  32.   strcpy (name, _fullName); temporary=_temporary;
  33.  
  34.   if (strcmp(name,"stdin")==0){
  35.     if (strchr(_mode,'r')==NULL){
  36.       throw generic_error("Cannot write to the standard input.");
  37.     }
  38.     fd=stdin; 
  39.   }
  40.   else if (strcmp(name,"stdout")==0){
  41.     if (strchr(_mode,'w')==NULL){
  42.       throw generic_error("Cannot read from the standard output."); 
  43.     }
  44.     fd=stdout;
  45.   }
  46.   else if ((fd=fopen(name, _mode))==NULL){throw file_error(name);}
  47. }
  48.  
  49. char TFile::getch(){
  50.   assert(fd!=NULL);
  51.   int ich; if(bufferCh==false || ch==0){
  52.     ich=fgetc(fd);ch=(ich>=0)?(char)ich:0;
  53.     if (ch!=0){currPos++;}
  54.     if (ch=='\n'){lineNumber++;currPos=0;}
  55.   }
  56.   bufferCh=false;   
  57.   return ch;
  58. }
  59.  
  60. char* TMemBlock::getstr(char* s, int size){
  61.   char* p=s; size--; /* make place for 0 terminator */
  62.   if (idx>=len){return NULL;}
  63.   do{
  64.     if (size--<=0){*s=0;return p;}
  65.     if (idx>=len){*s=0;return p;}
  66.     *s++=mem[idx++];
  67.   }while(mem[idx]!='\n');  
  68.   *s=0;
  69.   return p;
  70. }
  71.  
  72. char TMemBlock::getch(){
  73.   if (bufferCh==false || ch==0){
  74.     ch=(idx==len)?0:mem[idx++];    
  75.     if (ch!=0){currPos++;}
  76.     if (ch=='\n'){lineNumber++;currPos=0;}
  77.   }
  78.   bufferCh=false;
  79.   return ch;
  80. }
  81.  
  82. void TMemBlock::append(const char* s){
  83.   len+=strlen(s); if (len>=MEMBLOCK_LEN){
  84.     throw generic_error("Macro too big. Try increasing"
  85.                   " the MEMBLOCK_LEN in the Preproc.h.");}
  86.   strcat(mem,s);
  87. }
  88.  
  89. void TPreproc::insert(char* fullName){
  90.   lexer.flush();
  91.   PSource newItem(new TFile(fullName));
  92.   srcList.push (newItem); csrc=srcList.top();
  93. }
  94.  
  95. void TPreproc::insert(PSource srcP, bool copyParentInfo=true){
  96.   if (srcList.full()){throw generic_error("Recursive symbols ...");}
  97.   lexer.flush();
  98.   /* These memory blocks are usually used for macro replacements
  99.      or for anykind of internal string converters;
  100.      example algebraical parser.      
  101.      For that reason, these memory block should report
  102.      error in the current line of the file which was the last
  103.      being read.
  104.   */
  105.   if (copyParentInfo==true){
  106.     srcP->lineNumber=preproc.line();
  107.     srcP->currPos=preproc.curpos();
  108.     strcpy(srcP->name,preproc.name());
  109.   }
  110.   srcList.push (srcP); csrc=srcList.top();
  111. }
  112.  
  113. bool TPreproc::next(){
  114.   lexer.flush();
  115.   /* rotate stack */
  116.   if (fileN==0){fileN=srcList.capacity();}
  117.   if (fileN==0){throw generic_error("There is no open file.");}
  118.   srcList.rotateUp(); csrc=srcList.top();  
  119.   /* list stack */  
  120.   if (--fileN==0){return false;}else{return true;}
  121. }
  122.  
  123. char* TPreproc::getstr(char* s, int size){
  124.   char* returnString;
  125.   if (csrc()==NULL){return NULL;}
  126.   while( (returnString=csrc->getstr(s, size))==NULL){
  127.     srcList.pop();if (srcList.empty()){csrc=NULL;return NULL;}
  128.     csrc = srcList.top();
  129.   }
  130.   return returnString;
  131. }
  132.  
  133. char TPreproc::getch(){
  134.   char ch;
  135.   if (csrc()==NULL){return 0;}
  136.   while((ch=csrc->getch())==0){
  137.     strcpy(oldSourceName,csrc->name);
  138.     srcList.pop(); if (srcList.empty()){csrc=NULL;return 0;}
  139.     csrc=srcList.top();
  140.   }
  141.   return ch;
  142. }
  143.  
  144. void TPreproc::AddDir(){
  145.   char buf [LX_LINEBUF];
  146.   AddDir(syntax.Parse_FileName(buf));
  147. }
  148.  
  149. void TPreproc::AddDir(const char* directory){
  150.   dirList.push_back(directory);
  151. }
  152.  
  153. /* returns full pathname in filename_buf */
  154. char* TPreproc::FindFullPathName(char* filename_buf){
  155.   char buf [LX_LINEBUF]; strcpy(buf, filename_buf);
  156.   struct stat inpStat;
  157.   TstrCI dirCI = dirList.begin();
  158.   while (stat(buf, &inpStat)!=0){
  159.     if (dirCI==dirList.end()){throw file_error(filename_buf);}
  160.     strcpy(buf,(*dirCI).c_str()); strcat(buf,"/"); strcat(buf, filename_buf);
  161.     dirCI++;
  162.   }
  163.   strcpy(filename_buf, buf);    /* update filename string */
  164.   return filename_buf;
  165. }
  166.  
  167.